iT邦幫忙

2024 iThome 鐵人賽

DAY 16
0
Security

密碼學小白的學習之路系列 第 16

[Day 16] 中國餘式定理 & 題目(Modular-9)

  • 分享至 

  • xImage
  •  

中國餘式定理(Chinese Remainder Theorem,簡稱CRT)

  • 用於解決一系列同餘方程組的問題。

  • 《孫子算經》卷下第二十六題,叫做「物不知數」問題,原文如下:
    有物不知其數,三三數之剩二,五五數之剩三,七七數之剩二。問物幾何?
    也就是,一個整數除以三餘二,除以五餘三,除以七餘二,求這個整數。

等下的解法步驟就會解以這個為例。

  • 定理陳述:
    假設我們有以下同餘方程組:

x ≡ a₁ (mod m₁)
x ≡ a₂ (mod m₂)
...
x ≡ aₖ (mod mₖ)

其中 m₁, m₂, ..., mₖ 是兩兩互質的正整數。
那麼,這個方程組在模 M = m₁ * m₂ * ... * mₖ 的範圍內有唯一解。

解法步驟:

計算 M = m₁ * m₂ * ... * mₖ
對於每個方程,計算 Mᵢ = M / mᵢ
找到 Mᵢ 在模 mᵢ 下的逆元 yᵢ,即 Mᵢ * yᵢ ≡ 1 (mod mᵢ)
解是 x = (a₁ * M₁ * y₁ + a₂ * M₂ * y₂ + ... + aₖ * Mₖ * yₖ) mod M

假設我們要找一個數 x,滿足:

x ≡ 2 (mod 3)
x ≡ 3 (mod 5)
x ≡ 2 (mod 7)
步驟 1:
M = 3 * 5 * 7 = 105
步驟 2:
M₁ = 105 / 3 = 35
M₂ = 105 / 5 = 21
M₃ = 105 / 7 = 15
步驟 3:
35 * 2 ≡ 1 (mod 3), 所以 y₁ = 2
21 * 1 ≡ 1 (mod 5), 所以 y₂ = 1
15 * 1 ≡ 1 (mod 7), 所以 y₃ = 1
步驟 4:
x = (2 * 35 * 2 + 3 * 21 * 1 + 2 * 15 * 1) mod 105
= (140 + 63 + 30) mod 105
= 233 mod 105
= 23


  • 唯一性:
    如果兩個數在模 M 下同餘,且對每個 mᵢ 的餘數相同,那麼這兩個數必定相等,因為它們的差是 M 的倍數。
  • 解的範圍:
    解在模 M 的範圍內是唯一的,即 x + kM(k 為任意整數)也是解。
  • 原理:
    因為模數 m₁, m₂, ..., mₖ 互質,可以確保方程組有唯一解。當取模 mᵢ 時,只有相應的項不為 0,從而滿足每個方程。

詳細原理解釋與反證明:

a) 對於任意 j ≠ i,Mⱼ 是 mᵢ 的倍數(因為 Mⱼ 包含了除 mⱼ 外的所有 m)。
所以 Mⱼ ≡ 0 (mod mᵢ) 當 j ≠ i。

b) Mᵢ * yᵢ ≡ 1 (mod mᵢ),這是逆元的定義。

c) 因此,當我們對 mᵢ 取模時,除了第 i 項外,其他所有項都變為 0:

x ≡ (0 + ... + 0 + aᵢ * Mᵢ * yᵢ + 0 + ... + 0) (mod mᵢ)
≡ aᵢ * (Mᵢ * yᵢ) (mod mᵢ)
≡ aᵢ * 1 (mod mᵢ)
≡ aᵢ (mod mᵢ)

這就證明了我們所得的解確實滿足所有的同餘方程。

https://ithelp.ithome.com.tw/upload/images/20240822/201681652N3dw7IHaR.png

Chinese Remainder Theorem

https://cryptohack.org/courses/modular/crt1/

https://ithelp.ithome.com.tw/upload/images/20240822/20168165w4UChLo7Gg.png

題意:

介紹中國餘式定理求解,並告訴我們,可以從模數最大的同餘式開始,利用任意整數k,將x表示為x = a + kp的形式。

題目要我們找出一個整數x,使得x除以5餘2,除以11餘3,除以17餘5。
而我們要返回滿足下面這個式子的 a:
x ≡ a mod 935(題目要我們求出a)

解題過程

根據中國餘式定理的解題步驟,寫成python code,最後再返回 x % 935 的值。

a = [2, 3, 5]  # 給定的餘數列表
n = [5, 11, 17]  # 給定的模數列表
M = 1  # 初始化 M 為 1,M 將是所有模數的乘積

# 計算 M,M = m₁ * m₂ * ... * mₖ
for num in n:
    M *= num

# 計算每個 Mi,Mi = M / mi
Mi = [M // N for N in n]

# 初始化 y 為 0 的列表,將用來存放每個 Mi 的逆元
y = [0] * len(Mi)

x = 0

# 計算每個方程的解並累加到 x
for i in range(len(Mi)):
    y[i] = pow(Mi[i], -1, n[i])  # 計算 Mi 在模 n[i] 下的逆元 y[i]
    x += a[i] * Mi[i] * y[i]  # 累加每個方程的解到 x

x %= M

print(x % 935)

872

參考資料:

中國餘式定理:

後話:

今天查了中國餘式定理的相關資料,了解其解題步驟後也動手寫程式解題,收穫滿滿的一天(累死我了)。


上一篇
[Day 15] 題目(Modular-8) & Tonelli-Shanks算法 & 質數模4的分類
下一篇
[Day 17] 題目(Modular-10)
系列文
密碼學小白的學習之路31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言